home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $VER: graphics3Df.c 10.11 (02.03.98)
- **
- ** Main functions for graphics3D.library
- **
- ** (C) Copyright 97 Patrizio Biancalani
- ** All Rights Reserved.
- **
- ** Note: this code is traslate from the blitzbasic 3d graphics engine
- ** V 0.9 of Maciej R. Gorny.
- **
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <proto/exec.h>
- #include <proto/intuition.h>
- #include <intuition/intuition.h>
- #include <intuition/screens.h>
-
- #include <graphics/rastport.h>
- #include <graphics/clip.h>
- #include <graphics/regions.h>
- #include <graphics/gfx.h>
- #include <graphics/gfxmacros.h>
- #include <graphics/layers.h>
-
- #include "graphics3Dc.h"
- #include "graphics3D.h"
- #include "graphics3D2d.h"
- #include "graphics3Df_proto.h"
- #include "graphics3D2d_proto.h"
-
- /* Please note, that &PovedtBase always resides in register __a6 as well,
- but if we don't need it, we need not reference it here.
-
- Also note, that registers a0, a1, d0, d1 always are scratch registers,
- so you usually should only *pass* parameters there, but make a copy
- directly after entering the function. To avoid problems of kind
- "implementation defined behaviour", you should make a copy of A6 too,
- when it is actually used.
-
- In this example case, scratch register saving would not have been
- necessary (since there are no other function calls inbetween), but we
- did it nevertheless.
- */
-
- extern void buildlookuptables(struct ambient3d *in);
- extern void createworldtocamera(struct ambient3d *in);
- extern void recalcobj(struct ambient3d *in);
- extern long int t_removeobject(struct ambient3d *in);
- extern void localtoworld(struct ambient3d *in);
- extern void worldtocamera(struct ambient3d *in);
- extern void removebackfacesandshade(struct ambient3d *in);
- extern void clipobject3d(struct ambient3d *in);
- extern void generatepolylist(struct ambient3d *in);
- extern struct objectnode *resetobj(struct ambient3d *in);
- extern struct objectnode *nextobj(struct ambient3d *in);
- extern struct objectnode *pobj(struct ambient3d *in);
- extern void aggobj(struct ambient3d *in);
- extern void matidentity4x4(struct matrix4x4 *imatrix);
- extern void matzero4x4(struct matrix4x4 imatrix);
- extern void matcopy4x4(struct matrix4x4 *s_m,struct matrix4x4 *d_m);
- extern void matmult4x4(struct matrix4x4 *a,struct matrix4x4 *b,
- struct matrix4x4 *r);
- extern void matmult4x4s(struct matrix4x4 *a,struct matrix4x4 *b,
- struct matrix4x4 *r);
- extern void matmult1x4s(struct matrix1x4 *a,struct matrix4x4 *b,
- struct matrix1x4 *r);
- extern void makevector3d(struct vertex *a,struct vertex *b,
- struct vector *result);
- extern long int vectormag3d(struct vector *a);
- extern void normalpol(struct vertex *v0,struct vertex *v1,
- struct vertex *v2,struct vector *normal);
- extern long int dotproduct(struct vector *u,struct vector *v);
- extern long int sqri(long int v);
- extern long int abs(long int val);
- extern void qsort(long int lo0,long int hi0,long int *pol,long int *count);
- extern void paintpol(struct ambient3d *in,long int *iwp,
- long int total_polys,long int colb);
- extern long int quicksort(long int len,long int *pol);
-
- /**********************************************************/
-
- /****************************************************
- ** Routin per la gestione della grafica, in stile **
- ** 2.0 **
- ** (c) 1994 BIANCA HARD&SOFT Vers:1.00 **
- ****************************************************/
-
- /************ FUNZIONI 3D ********************************/
-
- /** macro ad uso interno e provvisorio **/
- #define mver(val) (val*sizeof(Svertex)+10)
- #define mobj(val) (val*sizeof(Sobjectnode)+5)
- #define mplf(val) (val*4+5)
- #define mtmp(val) (val*sizeof(Spolytemp)+5)
- #define tang (361*4+5)
- /****************************************/
-
- /************************************************
- * apertura e inizializzazione dell'ambiente 3D *
- * restituisce puntatore ad area generale da *
- * indicare sempre al richiamo delle altre *
- * routin. *
- ************************************************
- *** INPUT : *
- * win -> puntatore a finestra su cui si vuol *
- * operare. *
- * x0 -> coord. X origine finestra di vis. *
- * y0 -> coord. Y origine finestra di vis. *
- * scrw -> larghezza finestra per mondo 3D. *
- * scrh -> altezza finestra per mondo 3D. *
- * vdist-> distanza tra osservatore e piano di *
- * proiezione. *
- *** OUTPUT: *
- * puntatore a struttura ambient3d da usarsi in *
- * ingresso di quasi tutte le altre funzioni. *
- * > 0 allora tutto ok. *
- * <=0 allora errore, operazione fallita. *
- ************************************************/
- struct ambient3d *GD_display3d(win,x0,y0,scrw,scrh,vdist)
- REG(a0)struct Window *win;
- REG(d0)long int x0;
- REG(d1)long int y0;
- REG(d2)long int scrw;
- REG(d3)long int scrh;
- REG(d4)long int vdist;
- {
- long int i;
- char *p;
- struct ambient3d *ris;
- struct vector *vt;
- struct dir3d *dan3;
- struct Screen *sc;
- struct Layer *la;
- struct RastPort *rp;
-
- #ifdef DEBUG
- char dbg[80];
- #endif
-
- ris=NULL;
-
- ris=(struct ambient3d *)AllocMem(sizeof(Sambient3d),NULL);
- #ifdef DEBUG
- sprintf(dbg,"ambient3d=%ld\n",ris);
- write_dbg(dbg);
- #endif
- if ((long int)ris==NULL)
- {
- GD_close_display3d(ris);
- return(0);
- }
-
- /** inizializzo tutti i puntatori a 0 */
- ris->graf=0;
- ris->temp=0;
- ris->iobjects=0;
- ris->objects=0;
- ris->iwpolys=0;
- ris->worldpolys=0;
- ris->sintable=0;
- ris->costable=0;
-
- p=(char *)ini_g(win,5,scrw,scrh);
- #ifdef DEBUG
- sprintf(dbg,"ini_g=%ld\n",p);
- write_dbg(dbg);
- #endif
- if (p==(char *)NULL)
- {
- GD_close_display3d(ris);
- return(0);
- }
- ris->graf=(struct grafica *)p;
-
- p=(char *)AllocMem(mver(MAXVERT),NULL);
- if (p==(char *)NULL)
- {
- GD_close_display3d(ris);
- return(0);
- }
- ris->temp=p;
-
- p=(char *)AllocMem(mobj(MAXOBJECT),NULL);
- if (p==(char *)NULL)
- {
- GD_close_display3d(ris);
- return(0);
- }
- ris->objects=(struct objectnode *)p;
-
- p=(char *)AllocMem(mplf(MAXPLFRAM),NULL);
- if (p==(char *)NULL)
- {
- GD_close_display3d(ris);
- return(0);
- }
- ris->iwpolys=(long int *)p;
-
- p=(char *)AllocMem(mtmp(MAXPLFRAM),NULL);
- if (p==(char *)NULL)
- {
- GD_close_display3d(ris);
- return(0);
- }
- ris->worldpolys=(struct polytemp *)p;
-
- p=(char *)AllocMem(tang,NULL);
- #ifdef DEBUG
- sprintf(dbg,"sintable=%ld\n",p);
- write_dbg(dbg);
- #endif
- if (p==(char *)NULL)
- {
- GD_close_display3d(ris);
- return(0);
- }
- ris->sintable=(long int *)p;
-
- p=(char *)AllocMem(tang,NULL);
- #ifdef DEBUG
- sprintf(dbg,"costable=%ld\n",p);
- write_dbg(dbg);
- #endif
- if (p==(char *)NULL)
- {
- GD_close_display3d(ris);
- return(0);
- }
- ris->costable=(long int *)p;
-
- /** inizializzo tutte le variabili **/
- ris->win=win;
- ris->half_screen_width=(ris->graf->clipdx)/2;
- ris->half_screen_height=(ris->graf->clipdy)/2;
- ris->zoom=FIXV;
- ris->aspect_ratio=1*FIXV;
- ris->inv_aspect_ratio=1*FIXV;
- ris->viewing_distance=vdist;
- ris->minx=x0;
- ris->miny=y0;
- ris->maxx=ris->graf->clipdx;
- ris->maxy=ris->graf->clipdy;
- ris->agg_all=1;
- ris->gl_triangle_color=1;
- ris->gcolor=0;
- ris->ambient_light=1*FIXV;
- ris->projection_type=PROSP_P;
- vt=&ris->light_source;
-
- vt->x=234; /* =INT(0.913913*FIXV) */
- vt->y=100; /* =INT(0.389759*FIXV) */
- vt->z=-29; /* =INT(-0.113369*FIXV)*/
- vt->w=0;
-
- /*
- vt->x=1*FIXV;
- vt->y=-2*FIXV;
- vt->z=5*FIXV;
- vt->w=0*FIXV;
- */
- vt=&ris->view_point;
- vt->x=1*FIXV;
- vt->y=2*FIXV;
- vt->z=3*FIXV;
- vt->w=10*FIXV;
- dan3=&ris->view_angle;
- dan3->angx=0;
- dan3->angy=0;
- dan3->angz=0;
- ris->near_z=ris->viewing_distance;
- ris->far_z=4096;
- ris->bord_col=1;
- ris->clip_mode=ZPLANE;
- ris->view_mode=SOLID;
- ris->maxintensity=0;
- ris->total_polys=0;
- ris->total_objects=0;
- ris->attuale=0;
- ris->numero=1;
-
- /* installo una clipregion, per effettuare il clip automatico */
- i=clipbox(ris->graf,ris->minx,ris->miny,ris->maxx,ris->maxy);
- #ifdef DEBUG
- sprintf(dbg,"clipbox esi=%ld\n",i);
- write_dbg(dbg);
- #endif
- if (i==NULL)
- {
- GD_close_display3d(ris);
- return(0);
- }
-
- /** inizializzo tabelle seno e coseno **/
- buildlookuptables(ris);
-
- return(ris);
-
- }
-
- /************************************************
- * chiusura ed eliminazione dell'ambiente 3D *
- ************************************************
- *** INPUT : *
- * in -> valore >0 restituito da display3d. *
- *** OUTPUT: *
- * nessuno. *
- ************************************************/
- void GD_close_display3d(in)
- REG(a0)struct ambient3d *in;
- {
- long int i,n;
-
- if (in==NULL) return(0);
-
- if (in->total_objects>NULL)
- {
- n=in->total_objects;
- for(i=0 ; i<n ; i++)
- {
- in->attuale=0;
- GD_deleteobject(in);
- }
- }
- if (in->temp!=NULL) FreeMem(in->temp,mver(MAXVERT));
- if (in->sintable!=NULL) FreeMem(in->sintable,tang);
- if (in->costable!=NULL) FreeMem(in->costable,tang);
- if (in->iwpolys!=NULL) FreeMem(in->iwpolys,mplf(MAXPLFRAM));
- if (in->worldpolys!=NULL) FreeMem(in->worldpolys,mtmp(MAXPLFRAM));
- if (in->iobjects!=NULL) FreeMem(in->iobjects,NULL);
- if (in->objects!=NULL) FreeMem(in->objects,mobj(MAXOBJECT));
- if (in->graf!=NULL) close_g(in->graf);
-
- FreeMem(in,sizeof(Sambient3d));
-
- }
-
- /********************************************
- ** cambia il modo di visualizzazione **
- ** globale. **
- ********************************************
- *** INPUT : *
- * in -> valore >0 restituito da display3d.*
- * modo-> modalita' di visualizzazione *
- * oggetti. *
- * WIREF= wire frame *
- * SOLID= solid shade *
- * FLAT = flat shading *
- * b_col-> colore bordo, se <0 allora nessun*
- * bordo per i poligoni. *
- *** OUTPUT: *
- * >0 tutto ok. *
- * =0 valore non valido. *
- ********************************************/
- long int GD_changeviewmode(in,modo,b_col)
- REG(a0)struct ambient3d *in;
- REG(d0)long int modo;
- REG(d1)long int b_col;
- {
- struct objectnode *obj;
- long int buf;
-
- in->bord_col=b_col;
-
- if (modo!=WIREF AND modo!=SOLID AND modo!=FLAT) return(0);
-
- buf=in->attuale;
- obj=resetobj(in);
- while(obj!=NULL)
- {
- obj->shade=modo;
- obj->trasf|=0x01;
- obj=nextobj(in);
- }
-
- in->view_mode=modo;
- in->attuale=buf;
-
- return(1);
- }
-
- /********************************************
- ** cambia il modo di visualizzazione **
- ** dell'oggetto attualmente selezionato. **
- ********************************************
- *** INPUT : *
- * in -> valore >0 restituito da display3d.*
- * modo-> modalita' di visualizzazione *
- * oggetti. *
- * WIREF= wire frame *
- * SOLID= solid shade *
- * FLAT = flat shading *
- *** OUTPUT: *
- * >0 tutto ok. *
- * =0 valore non valido. *
- ********************************************/
- long int GD_changeviewmodeobj(in,modo)
- REG(a0)struct ambient3d *in;
- REG(d0)long int modo;
- {
- struct objectnode *obj;
-
- if (modo!=WIREF AND modo!=SOLID AND modo!=FLAT) return(0);
-
- obj=pobj(in);
-
- obj->shade=modo;
- obj->trasf|=0x01;
-
- return(1);
- }
-
- /**********************************************
- ** crea una palette sfumata tra due colori **
- ** nella palette dello schermo, in modo di **
- ** poter poi usare il FLAT SHADING. **
- **********************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- * fr -> n# primo registro colore da settare. *
- * lr -> n# ultimo reg. colore da settare. *
- * init_color -> punt. a struttura rgbtype *
- * con valore rgb iniz. colore. *
- * last_color -> punt. a struttura rgbtype *
- * con valore rgb fin. color. *
- *** OUTPUT: *
- * nessuno. *
- **********************************************/
- void GD_touchpalette(in,fr,lr,init_color,last_color)
- REG(a0)struct ambient3d *in;
- REG(d0)long int fr;
- REG(d1)long int lr;
- REG(a1)struct rgbtype *init_color;
- REG(a2)struct rgbtype *last_color;
- {
- long int m,t,i,fc,lc;
- long int *temp_red,*temp_green,*temp_blue,*temp;
-
- temp=AllocMem(900*sizeof(long int),NULL);
- if ((long int)temp>NULL)
- {
- temp_red=&temp[0];
- temp_green=&temp[300];
- temp_blue=&temp[600];
-
- m=lr-fr-1;
- if (in->maxintensity<m OR in->maxintensity==NULL)
- in->maxintensity=m;
-
- lc=last_color->r;
- fc=init_color->r;
- t=(lc-fc)/(lr-fr);
- for(i=fr ;i<=lr ;i++) temp_red[i-fr]=fc+t*(i-fr);
-
- lc=last_color->g;
- fc=init_color->g;
- t=(lc-fc)/(lr-fr);
- for(i=fr ;i<=lr ;i++) temp_green[i-fr]=fc+t*(i-fr);
-
- lc=last_color->b;
- fc=init_color->b;
- t=(lc-fc)/(lr-fr);
- for(i=fr ;i<=lr ;i++) temp_blue[i-fr]=fc+t*(i-fr);
-
- for(i=0 ;i<lr-fr+1 ;i++)
- GD_rgb4(in,i+fr,temp_red[i],temp_green[i],temp_blue[i]);
-
- FreeMem(temp,900*sizeof(long int));
- }
-
- }
-
- /**********************************************
- ** muove l'osservatore di dist unita' **
- **********************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- * dist -> numero di unita' di spostamento. *
- * (il valore deve essere FIXPOINT) *
- *** OUTPUT: *
- * nessuno. *
- **********************************************/
- void GD_moveforward(in,dist)
- REG(a0)struct ambient3d *in;
- REG(d0)long int dist;
- {
- long int *sin,*cos;
- struct dir3d *vang;
- struct vector *vp;
- long int active_axes,dx,dy,dz;
-
- sin=in->sintable;
- cos=in->costable;
- vang=&in->view_angle;
- vp=&in->view_point;
-
- active_axes=0;
-
- if (vang->angx!=NULL) active_axes+=1;
- if (vang->angy!=NULL) active_axes+=2;
- if (vang->angz!=NULL) active_axes+=4;
-
- switch (active_axes)
- {
- case (0):
- dx=0;
- dy=0;
- dz=dist;
- break;
- case (1):
- dx=0;
- dy=(dist*cos[vang->angx]) >> SFIXV;
- dz=(dist*sin[vang->angx]) >> SFIXV;
- break;
- case (2):
- dx=(dist*sin[vang->angy]) >> SFIXV;
- dy=0;
- dz=(dist*cos[vang->angy]) >> SFIXV;
- break;
- case (3):
- dx=(dist*sin[vang->angy]) >> SFIXV;
- dy=(dist*cos[vang->angx]) >> SFIXV;
- dz=(dist*cos[vang->angy]) >> SFIXV +
- (dist*sin[vang->angx]) >> SFIXV;
- break;
- case (4):
- dx=(dist*sin[vang->angz]) >> SFIXV;
- dy=(dist*cos[vang->angz]) >> SFIXV;
- dz=0;
- break;
- case (5):
- dx=(dist*sin[vang->angz]) >> SFIXV;
- dy=(dist*cos[vang->angx]) >> SFIXV +
- (dist*cos[vang->angz]) >> SFIXV;
- dz=(dist*sin[vang->angx]) >> SFIXV;
- break;
-
- case (6):
- dx=(dist*sin[vang->angy]) >> SFIXV +
- (dist*sin[vang->angz]) >> SFIXV;
- dy=(dist*cos[vang->angz]) >> SFIXV;
- dz=(dist*cos[vang->angy]) >> SFIXV;
- break;
-
- case (7):
- dx=(dist*sin[vang->angy]) >> SFIXV +
- (dist*sin[vang->angz]) >> SFIXV;
- dy=(dist*cos[vang->angx]) >> SFIXV +
- (dist*cos[vang->angz]) >> SFIXV;
- dz=(dist*sin[vang->angx]) >> SFIXV +
- (dist*cos[vang->angy]) >> SFIXV;
- break;
-
- }
-
- vp->x+=dx;
- vp->y+=dy;
- vp->z+=dz;
-
- /* forzo aggiornamento di TUTTA la scena */
- in->agg_all=1;
-
- }
-
- /**********************************************
- ** cambio l'angolo della visuale **
- **********************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- * ax -> valore rotazione su asse x. *
- * (in gradi e intero) *
- * ay -> valore rotazione su asse y. *
- * (in gradi e intero) *
- * az -> valore rotazione su asse z. *
- * (in gradi e intero) *
- *** OUTPUT: *
- * nessuno. *
- **********************************************/
- void GD_viewangle(in,ax,ay,az)
- REG(a0)struct ambient3d *in;
- REG(d0)long int ax;
- REG(d1)long int ay;
- REG(d2)long int az;
- {
- struct dir3d *va;
- long int ta;
-
- va=&in->view_angle;
-
- if (ax<0 OR ax>360)
- {
- ta=ax/360;
- ax-=ta*360;
- if (ax<0) ax+=360;
- }
-
- if (ay<0 OR ay>360)
- {
- ta=ay/360;
- ay-=ta*360;
- if (ay<0) ay+=360;
- }
-
- if (az<0 OR az>360)
- {
- ta=az/360;
- az-=ta*360;
- if (az<0) az+=360;
- }
-
- va->angx=ax;
- va->angy=ay;
- va->angz=az;
-
- /* forzo aggiornamento di TUTTA la scena */
- in->agg_all=1;
-
- }
-
- /******************************************************
- ** setta i piani near e far del volume visualizzato **
- ******************************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- * near -> posizione piano vicino.(valore intero) *
- * far -> posizione piano lontano.(valore intero) *
- *** OUTPUT: *
- * nessuno. *
- ******************************************************/
- void GD_frustum(in,near,far)
- REG(a0)struct ambient3d *in;
- REG(d0)long int near;
- REG(d1)long int far;
- {
- long int n,f;
- /* i valori in input devono essere interi */
- n=near;
- f=far;
- if (near<in->viewing_distance) n=in->viewing_distance;
- if (far<near) f=2*n;
-
- in->near_z=n;
- in->far_z=f;
-
- }
-
- /******************************************************
- ** crea e posiziona una sorgente di luce . **
- ******************************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- * x -> valore coordinata X luce(valore FIXPOINT). *
- * y -> valore coordinata Y luce(valore FIXPOINT). *
- * z -> valore coordinata Z luce(valore FIXPOINT). *
- *** OUTPUT: *
- * nessuno. *
- ******************************************************/
- void GD_createlightsource(in,x,y,z)
- REG(a0)struct ambient3d *in;
- REG(d0)long int x;
- REG(d1)long int y;
- REG(d2)long int z;
- {
- struct vertex v1,v2;
-
- /* i valori in ingresso devono gia' essere in fixpoint */
- v1.x=x;
- v1.y=y;
- v1.z=z;
- v2.x=0;
- v2.y=0;
- v2.z=0;
-
- makevector3d(&v1,&v2,&in->light_source);
-
- /* forzo aggiornamento scena */
- in->agg_all=1;
-
- }
-
- /**********************************************
- ** setta l'intensita' di luce ambientale. **
- **********************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- * inte-> valore intensita' luce *
- * (valore in FIXPOINT). *
- *** OUTPUT: *
- * nessuno. *
- **********************************************/
- void GD_ambientlight(in,inte)
- REG(a0)struct ambient3d *in;
- REG(d0)long int inte;
- {
-
- /* il valore di input deve essere in fixpoint */
- in->ambient_light=inte;
-
- if (inte>>SFIXV > in->maxintensity) inte=in->maxintensity<<SFIXV;
- if (inte<NULL) inte=0;
-
- /* forzo aggiornamento scena */
- in->agg_all=1;
-
- }
-
- /************************************************
- ** posiziona il punto di vista nel mondo 3d. **
- ************************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- * x -> valore coordinata X camera *
- * (valore FIXPOINT). *
- * y -> valore coordinata Y camera *
- * (valore FIXPOINT). *
- * z -> valore coordinata Z camera *
- * (valore FIXPOINT). *
- *** OUTPUT: *
- * nessuno. *
- ************************************************/
- void GD_positioncamera(in,x,y,z)
- REG(a0)struct ambient3d *in;
- REG(d0)long int x;
- REG(d1)long int y;
- REG(d2)long int z;
- {
-
- /* i valori in input devono gia' essere in fixpoint */
- in->view_point.x=x;
- in->view_point.y=y;
- in->view_point.z=z;
-
- /* forzo aggiornamento scena */
- in->agg_all=1;
-
- }
-
- /************************************************
- ** variazione aspect ratio scena. **
- ************************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- * ratio-> nuovo aspect ratio.(valore FIPOINT). *
- *** OUTPUT: *
- * nessuno. *
- ************************************************/
- void GD_aspectratio(in,ratio)
- REG(a0)struct ambient3d *in;
- REG(d0)long int ratio;
- {
-
- in->aspect_ratio=ratio;
- in->inv_aspect_ratio=FIXV*FIXV/ratio;
-
- }
-
- /************************************************
- ** setta un particolare modo per il clipping. **
- ************************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- * mode -> nuovo modo di clipping. *
- * (ZPLANE ,FRUSTUM). *
- *** OUTPUT: *
- * nessuno. *
- ************************************************/
- void GD_clipmode(in,mode)
- REG(a0)struct ambient3d *in;
- REG(d0)long int mode;
- {
-
- in->clip_mode=mode;
- if (mode!=FRUSTUM AND mode!=ZPLANE) in->clip_mode=ZPLANE;
-
- }
-
- /************************************************
- ** trova l'oggetto e il poligono al cui **
- ** interno risiede il punto dato. **
- ************************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- * np -> puntatore a long, dove mettere n# pol. *
- * al cui interno risiede il punto. *
- * xp -> coordinata x punto dato nella finestra *
- * in cui e' visualizzata la scena. *
- * (valore intero). *
- * yp -> coordinata y punto dato nella finestra *
- * in cui e' visualizzata la scena. *
- * (valore intero). *
- *** OUTPUT: *
- * = 0 nessun oggetto trovato. *
- * (in questo caso valore in np senza sign.)*
- * > 0 valore identificativo oggetto trovato. *
- *** NOTA: *
- * L'algoritmo che ho usato sembra funzioni ma *
- * e' stato trovato in modo del tutto empirico *
- * se qualcuno mi sa spiegare perche' funzioni *
- * e' il benvenuto. *
- ************************************************/
- long int GD_pickobj(in,np,xp,yp)
- REG(a0)struct ambient3d *in;
- REG(a1)long int *np;
- REG(d0)long int xp;
- REG(d1)long int yp;
- {
- struct polytemp *plt;
- long int *ip,id,i,ris;
- long int x,y,xm,ym,x1,x2,x3,y1,y2,y3;
-
- ip=in->iwpolys;
- ris=0;
- i=in->total_polys-1;
-
- #ifdef OPTG
- x=xp-in->minx;
- y=yp-in->miny;
- #else
- x=xp;
- y=yp;
- #endif
-
- while ((i>=0 AND ris==0))
- {
- plt=(struct polytemp *)ip[i];
- /* traslo origini poligono su punto dato */
- x1=plt->x1-x;
- y1=plt->y1-y;
- x2=plt->x2-x;
- y2=plt->y2-y;
- x3=plt->x3-x;
- y3=plt->y3-y;
- /* calcolo massimo x e y del triangolo (in valore assoluto)*/
- xm=abs(x1);
- if (abs(x2)>xm) xm=abs(x2);
- if (abs(x3)>xm) xm=abs(x3);
- ym=abs(y1);
- if (abs(y2)>ym) ym=abs(y2);
- if (abs(y3)>ym) ym=abs(y3);
- /* sommo gli assi dei tre vertici tra loro */
- x1=abs(x1+x2+x3);
- y1=abs(y1+y2+y3);
- /* test se risultato in valore assoluto maggiore dei val. massimi per x e y*/
- /* se no, punto interno altrimenti esterno */
- if (x1<=xm AND y1<=ym)
- {
- ris=plt->obj;
- np[0]=plt->npol;
- }
- /* se poligono composto di 4 lati ripeto il test per l'altro triangolo */
- if (plt->numpoints=4)
- {
- /* traslo origini poligono su punto dato */
- x1=plt->x3-x;
- y1=plt->y3-y;
- x2=plt->x4-x;
- y2=plt->y4-y;
- x3=plt->x1-x;
- y3=plt->y1-y;
- xm=abs(x1);
- if (abs(x2)>xm) xm=abs(x2);
- if (abs(x3)>xm) xm=abs(x3);
- ym=abs(y1);
- if (abs(y2)>ym) ym=abs(y2);
- if (abs(y3)>ym) ym=abs(y3);
- x1=abs(x1+x2+x3);
- y1=abs(y1+y2+y3);
- if (x1<=xm AND y1<=ym)
- {
- ris=plt->obj;
- np[0]=plt->npol;
- }
- }
- i--;
- }
-
- return(ris);
-
- }
-
- /************************************************
- ** crea e inizializza una nuova struttura **
- ** oggetto e tutte le sue sottostrutture. **
- ** Lo fa diventare l'attuale. **
- ************************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- * name -> puntatore a stringa con nome oggetto.*
- * pol -> n# totale poligoni nell'oggetto. *
- * vert -> n# totale vertici nell'oggetto. *
- *** OUTPUT: *
- * > 0 tutto ok, rende n# identificatore oggetto*
- * =0 errore, operazione fallita. *
- ************************************************/
- long int GD_newobj(in,name,pol,vert)
- REG(a0)struct ambient3d *in;
- REG(a1)char *name;
- REG(d0)long int pol;
- REG(d1)long int vert;
- {
- long int i,id,lv;
- struct objectnode *ob;
- char *n;
-
- id=in->total_objects;
- if (id>MAXOBJECT) return(0);
- if (vert>MAXVERT) return(0);
-
- in->total_objects+=1;
-
- in->attuale=id;
- ob=pobj(in);
-
- n=ob->name;
-
- i=0;
- while(i<21 OR name[i]!=0x00) n[i]=name[i++];
- n[i]=0x00;
-
- /** inizializzo valori di default */
- ob->numpolys=pol;
- ob->numverts=vert;
- ob->vorig=0;
- ob->vlocal=0;
- ob->vcamera=0;
- ob->polys=0;
- ob->state=1;
- ob->shade=in->view_mode;
- ob->trasf=1;
-
- /* definisco origine oggetto alle coordinate 0,0,0 */
- ob->worldposx=0;
- ob->worldposy=0;
- ob->worldposz=0;
-
- lv=vert*sizeof(Svertex);
-
- n=(char *)AllocMem(lv,NULL);
- if (n<=(char *)NULL)
- {
- GD_deleteobject(in);
- return(0);
- }
- ob->vorig=(struct vertex *)n;
-
- n=(char *)AllocMem(lv,NULL);
- if (n<=(char *)NULL)
- {
- GD_deleteobject(in);
- return(0);
- }
- ob->vlocal=(struct vertex *)n;
-
- n=(char *)AllocMem(lv,NULL);
- if (n<=(char *)NULL)
- {
- GD_deleteobject(in);
- return(0);
- }
- ob->vcamera=(struct vertex *)n;
-
- n=(char *)AllocMem(pol*sizeof(Spolygon),NULL);
- if (n<=(char *)NULL)
- {
- GD_deleteobject(in);
- return(0);
- }
- ob->polys=(struct polygon *)n;
-
- ob->id=in->numero;
- in->numero+=1;
-
- return(ob->id);
-
- }
-
- /************************************************
- ** elimina oggetto attuale e libera la memoria**
- ************************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- *** OUTPUT: *
- * nessuno. *
- ************************************************/
- void GD_deleteobject(in)
- REG(a0)struct ambient3d *in;
- {
- struct objectnode *ob;
- char *s,*d;
- long int sob,i;
-
- if (in->total_objects==NULL) return(0);
-
- sob=sizeof(Sobjectnode);
- ob=pobj(in);
-
- i=sizeof(Svertex)*ob->numverts;
-
- if (ob->vorig!=NULL) FreeMem(ob->vorig,i);
- if (ob->vlocal!=NULL) FreeMem(ob->vlocal,i);
- if (ob->vcamera!=NULL) FreeMem(ob->vcamera,i);
- if (ob->polys!=NULL) FreeMem(ob->polys,sizeof(Spolygon)*ob->numpolys);
-
- in->total_objects-=1;
- if (in->attuale>=in->total_objects)
- {
- in->attuale=in->total_objects-1;
- return(0);
- }
-
- /* elimino i dati dell'oggetto */
- /*cmem(ob+sob,ob,mul(in.total_objects-in.attuale-1,sob))*/
- /** !!!attenzione!!! questa routin in questo caso e' ok ***/
- /** ma se si devono spostare aree sovrapposte non va piu' bene **/
- d=(char *)ob;
- s=(char *)ob+sob;
- for(i=0 ; i<(in->total_objects-in->attuale)*sob ; i++) d[i]=s[i];
-
- }
-
- /************************************************
- ** inserisce un vertice nell'oggetto corrente.**
- ************************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- * num -> numero indice del vertice da inserire *
- * (#1 = 0, #2 = 1, ...). *
- * x -> valore coordinata x vertice *
- * (in FIXPOINT) *
- * y -> valore coordinata y vertice *
- * (in FIXPOINT) *
- * z -> valore coordinata z vertice *
- * (in FIXPOINT) *
- *** OUTPUT: *
- * > 0 tutto ok, vertice inserito. *
- * = 0 operazione fallita. *
- *** NOTA : *
- * Se si cerca di inserire un vertice con indice*
- * maggiore del numero di vertici definiti per *
- * l'oggetto l'operazione fallira'. *
- ************************************************/
- long int GD_addobjvertex(in,num,x,y,z)
- REG(a0)struct ambient3d *in;
- REG(d0)long int num;
- REG(d1)long int x;
- REG(d2)long int y;
- REG(d3)long int z;
- {
- struct objectnode *obj;
- struct vertex *vl,*vo;
-
- obj=pobj(in);
-
- vl=obj->vlocal;
- vo=obj->vorig;
-
- if (num+1>obj->numverts) return(0);
- if (num<NULL) return(0);
-
- vl[num].x=x;
- vo[num].x=x;
- vl[num].y=y;
- vo[num].y=y;
- vl[num].z=z;
- vo[num].z=z;
-
- return(1);
- }
-
- /************************************************
- ** inserisce un poligono all'oggetto corrente **
- ** se p4=-1 allora poligono a 3 vertici. **
- ************************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- * num -> numero indice del poligono da inserire*
- * (#1 = 0, #2 = 1, ...). *
- * p1 -> numero indice primo punto pol. su *
- * elenco vertico oggetto. *
- * p2 -> numero indice secondo punto pol. su *
- * elenco vertico oggetto. *
- * (=-1 allora poligono a un vertice). *
- * p3 -> numero indice terzo punto pol. su *
- * elenco vertico oggetto. *
- * (=-1 allora poligono a due vertici). *
- * p4 -> numero indice quarto punto pol. su *
- * elenco vertico oggetto . *
- * (=-1 allora poligono a tre vertici). *
- *** OUTPUT: *
- * > 0 tutto ok, poligono inserito. *
- * = 0 operazione fallita. *
- *** NOTA : *
- * Se si cerca di inserire un poligono con *
- * indice maggiore del numero di poligoni *
- * definiti per l'oggetto l'operazione fallira'.*
- ************************************************/
- long int GD_addobjpoly(in,num,p1,p2,p3,p4)
- REG(a0)struct ambient3d *in;
- REG(d0)long int num;
- REG(d1)long int p1;
- REG(d2)long int p2;
- REG(d3)long int p3;
- REG(d4)long int p4;
- {
- struct objectnode *obj;
- struct polygon *poly;
- struct vertex *vert;
- long int t;
-
- obj=pobj(in);
- poly=obj->polys;
- vert=obj->vorig;
-
- if (num+1>obj->numpolys) return(0);
- if (num<NULL) return(0);
-
- t=1;
- if (p1<NULL) return(0);
- if (p2>=NULL) t++;
- if (p3>=NULL) t++;
- if (p4>=NULL) t++;
-
- poly[num].numpoints=t;
- poly[num].twosided=1; /* default poligono a due facce */
- poly[num].visible=1;
- poly[num].clipped=0;
- poly[num].active=1;
- poly[num].vertexlist0=p1;
- if (t>1) poly[num].vertexlist1=p2;
- if (t>2) poly[num].vertexlist2=p3;
- if (t>3) poly[num].vertexlist3=p4;
-
- return(1);
- }
-
- /************************************************
- ** cambia le caratteristiche di un poligono. **
- ************************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- * num -> numero indice del poligono da variare *
- * (#1 = 0, #2 = 1, ...). *
- * color -> colore base per oggetto, in caso di *
- * visualizzazione flat usera i colori *
- * successivi a questo per sfumare. *
- * twoside -> indica se poligono a 2 facce (1) o*
- * a una faccia (0). *
- * Se a due facce sara' visibile solo*
- * la faccia frontale. *
- *** OUTPUT: *
- * > 0 tutto ok, poligono modificato. *
- * = 0 operazione fallita. *
- *** NOTA : *
- * Se si cerca di modificare un poligono con *
- * indice maggiore del numero di poligoni *
- * definiti per l'oggetto l'operazione fallira'.*
- ************************************************/
- long int GD_cattpoly(in,num,color,twoside)
- REG(a0)struct ambient3d *in;
- REG(d0)long int num;
- REG(d1)long int color;
- REG(d2)long int twoside;
- {
- struct objectnode *obj;
- struct polygon *poly;
-
- obj=pobj(in);
- poly=obj->polys;
-
- if (num+1>obj->numpolys) return(0);
- if (num<NULL) return(0);
-
- if (poly[num].numpoints>2) poly[num].twosided=twoside;
- poly[num].color=color;
-
- return(1);
- }
-
- /************************************************
- ** Setta come attuale l'oggetto di cui e'dato **
- ** l'identificativo. **
- ************************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- * num -> identificativo oggetto da settare. *
- *** OUTPUT: *
- * > 0 tutto ok, *
- * = 0 operazione fallita. *
- ************************************************/
- long int GD_setobj(in,num)
- REG(a0)struct ambient3d *in;
- REG(d0)long int num;
- {
- long int ris,buf;
- struct objectnode *obj;
-
- ris=0;
- if (num==0) return(0);
- buf=in->attuale;
- obj=resetobj(in);
- while ((obj!=0 AND ris==0))
- {
- if (num==obj->id)
- {
- ris=1;
- }
- else
- {
- obj=nextobj(in);
- }
- }
-
- if (ris==NULL) in->attuale=buf;
- return(ris);
-
- }
-
- /************************************************
- ** Ritorna l'identificativo dell'oggetto **
- ** attuale. **
- ************************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- *** OUTPUT: *
- * >0 tutto ok, valore identificativo. *
- * = 0 operazione fallita. *
- ************************************************/
- long int GD_getobj(in)
- REG(a0)struct ambient3d *in;
- {
- struct objectnode *obj;
-
- obj=pobj(in);
-
- return(obj->id);
-
- }
-
- /*************************************
- ** ROUTIN PER CABIARE IL COLORE **
- ** DI UN REGISTRO DELLA PALETTE **
- *************************************
- **** INPUT : **
- ** graf ->valore non 0 ritornato da**
- ** display3d. **
- ** nr ->numero registro da **
- ** variare. **
- ** red ->livello rosso (0-15). **
- ** green->livello verde (0-15). **
- ** blue ->livello blu (0-15). **
- **** OUTPUT: **
- ** nessuno. **
- *************************************/
- void GD_rgb4(REG(a0)struct ambient3d *in,REG(d0)long int n,
- REG(d1)long int red,REG(d2)long int green,REG(d3)long int blue)
- {
- struct grafica *graf;
-
- graf=in->graf;
- if (((long int)graf<=NULL) OR ((long int)(graf->vpor)<=NULL)) return(0);
-
- SetRGB4(graf->vpor,n,red,green,blue);
- }
-
- /******************************************************
- ** visualizza effettivamente i poligoni nella frame **
- ** corrente. Ordina i poligoni in base alla Z max. **
- ******************************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- *** OUTPUT: *
- * puntatore a RastPort su cui si e' disegnato. *
- * In caso di libreria ottimizzato e' quello della *
- * finestra di visualizzazione. *
- ******************************************************/
- struct RastPort *GD_paintframe(in)
- REG(a0)struct ambient3d *in;
- {
- long int it,buf;
-
- it=0;
-
- /** riordino tutti i poligoni in base alla loro distanza **/
- /** dall'osservatore. **/
- /** si effettua solo se il modo di visualizzazione non **/
- /** e' WIREFRAME (ho usato il quicksort) **/
- if (in->view_mode!=WIREF) it=quicksort(in->total_polys,in->iwpolys);
-
- buf=in->graf->rast->DrawMode;
- /* ripulisco la frame attuale */
- cls_f(in);
-
- over(in->graf,1);
-
- /** inizio la visualizzazione vera e propia della frame attuale **/
- paintpol(in,in->iwpolys,in->total_polys,in->bord_col);
-
- over(in->graf,buf);
-
- return (in->graf->rast);
- }
-
- /**********************************************
- ** ri-calcola la vista del mondo 3d. **
- **********************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- *** OUTPUT: *
- * nessuno. *
- **********************************************/
- void GD_newview(in)
- REG(a0)struct ambient3d *in;
- {
- struct objectnode *obj;
- long int buf;
-
- /*
- #ifdef DEBUG
- char dbg[80];
- #endif
- */
-
- createworldtocamera(in);
-
- /* resetlist() */
- buf=in->attuale;
- obj=resetobj(in);
-
- /*
- #ifdef DEBUG
- sprintf(dbg,"*** INIZIO RICALCOLO SCENA ***\n");
- write_dbg(dbg);
- #endif
- */
-
- do
- /** non cambiare l'ordine d'esecuzione delle routin in questo loop MAI! **/
- {
- GD_recalcobj(in);
- if (obj->trasf!=NULL OR in->agg_all!=NULL)
- {
- if (t_removeobject(in)==NULL)
- {
- localtoworld(in);
- removebackfacesandshade(in);
- worldtocamera(in);
- #ifndef OPTG
- clipobject3d(in);
- #endif
- }
- }
- /* reset segnalazione di trasformazioni multiple */
- obj->trasf=0;
- obj=nextobj(in);
-
- }while(obj!=NULL);
-
- /*
- #ifdef DEBUG
- sprintf(dbg,"*** FINE RICALCOLO SCENA ***\n\n");
- write_dbg(dbg);
- #endif
- */
-
- generatepolylist(in);
-
- /* resetto flag per forzare aggiornamento scena */
- in->agg_all=0;
-
- /* ripristino oggetto attualmente selezionato */
- in->attuale=buf;
-
- }
-
- /************************************************
- ** aggiorna tutti i dati precalcolati dello **
- ** oggetto attuale. **
- ************************************************
- *** INPUT : *
- * in -> valore > 0 restituito da display3d. *
- *** OUTPUT: *
- * nessuno. *
- *** NOTA : *
- * Il ricalcolo si effettua solo se l'oggetto e'*
- * stato effettivamente modificato. *
- ************************************************/
- void GD_recalcobj(in)
- REG (a0)struct ambient3d *in;
- {
- struct objectnode *obj;
-
- obj=pobj(in);
-
- if (obj->trasf!=NULL OR in->agg_all!=NULL)
- {
- if (obj->trasf & 0x01!=NULL) aggobj(in);
- }
-
- }
- /********** FUNZIONI 2D *************************/
- /************************************
- ** FUNZIONE PER DEFINIRE UN BOX **
- ** DI CLIP SULLA FINESTRA **
- ************************************
- **** INPUT : **
- ** in -> valore >0 ritornato **
- ** dalla funzione d'ini- **
- ** zializzazione display3d**
- ** minx - valore minimo x box. **
- ** miny - valore minimo y box. **
- ** dx - larghezza box. **
- ** dy - altezza box. **
- **** OUTPUT: **
- ** > 0 tutto ok valore dx. **
- ** = 0 errore. **
- **** NOTA: **
- ** se valori in input tutti a zero**
- ** elimina l'area di clip. **
- ************************************/
- long int GD_clipbox(REG(a0)struct ambient3d *in,REG(d0)long int minx,
- REG(d1)long int miny,REG(d2)long int dx,REG(d3)long int dy)
- {
- long int ris;
- struct Window *win;
-
- ris=clipbox(in->graf,minx,miny,dx,dy);
- if (ris=NULL) return(ris);
-
- win=in->win;
-
- in->half_screen_width=ris/2;
- in->half_screen_height=dy/2;
- in->minx=minx;
- in->miny=miny;
- in->maxx=ris;
- in->maxy=dy;
-
- return(ris);
-
- }
-
- /************************************
- ** FUNZIONE PER VISUALIZZARE LA **
- ** RASTPORT NASCOSTA SULLA **
- ** FINESTRA. **
- ************************************
- **** INPUT : **
- ** in -> valore >0 ritornato **
- ** dalla funzione d'ini- **
- ** zializzazione display3d**
- **** OUTPUT: **
- ************************************/
- void GD_switch_rp(in)
- REG(a0)struct ambient3d *in;
- {
-
- switch_rp(in->graf);
-
- }
-
- /*****************************************
- ** FUNZIONE PER VARIARE CARATTERISTCHE **
- ** SCENA 3D. **
- *****************************************
- **** INPUT : **
- ** in -> valore >0 ritornato dalla **
- ** funzione d'inizializzazione **
- ** display3d(). **
- ** new-> puntatore a array di strutture**
- ** tag3d con nuovi valori. **
- **** OUTPUT: **
- ** == 0 - nessuna variazione . **
- ** > 0 - n# variazioni eseguite. **
- *****************************************/
- long int GD_cascene(in,new)
- REG(a0)struct ambient3d *in;
- REG(a1)struct tag3d *new;
- {
- long int ris,i,ct,ft;
-
-
- ris=0;
- ct=0;
-
- while(new[ct].tipo!=END_T AND ct<1000)
- {
- ft=new[ct].tipo;
- i=new[ct].val;
- switch(ft)
- {
- case(CS_PROJET):
- /* cambio tipo di proiezione */
- if (i==PROSP_P OR i==PARAL_P)
- {
- in->projection_type=i;
- in->agg_all=1;
- ris+=1;
- }
- break;
- case(CS_ZOOM):
- /* cambio valore zoom scena */
- if (i<256*FIXV)
- {
- in->zoom=i;
- in->agg_all=1;
- ris+=1;
- }
-
- case(CS_VDIST):
- /* sposto distanza osservatore dal piano di proiezione */
- if (i<=in->near_z OR i<=in->far_z)
- {
- in->viewing_distance=i;
- in->agg_all=1;
- ris+=1;
- }
- break;
-
- case(CS_NPX0):
- /* sposto X0 box scena 3d nella sua finestra */
- in->minx=i;
- clipbox(in->graf,in->minx,in->miny,
- in->maxx,in->maxy);
- in->agg_all=1;
- ris+=1;
- break;
-
- case(CS_NPY0):
- /* sposto Y0 box scena 3d nella sua finestra */
- in->miny=i;
- clipbox(in->graf,in->minx,in->miny,
- in->maxx,in->maxy);
- in->agg_all=1;
- ris+=1;
- break;
-
- case(CS_GCOLOR):
- /* cambio colore fondo a scena 3d */
- in->gcolor=i;
- in->agg_all=1;
- ris+=1;
- break;
-
- }
- ct+=1;
- }
-
- return(ris);
- }
-
- /*************************************
- ** FUNZIONE PER PASSARE DA INTERO **
- ** A FIXPOINT. **
- *************************************
- **** INPUT : **
- ** in -> puntatore a intero long **
- ** con valore da convertire. **
- ** out-> puntatore a intero long **
- ** con valore convertito. **
- **** OUTPUT: **
- ** ==0 -> tutto ok. **
- ** <>0 -> errore out non modificato**
- *************************************/
- long int GD_int2fix(in,out)
- REG(a0)long int *in;
- REG(a1)long int *out;
- {
- long int bf,bf1;
-
- bf=in[0];
-
- /* calcolo massimo valore convertibile */
- bf1=0x7fffffff >> SFIXV;
-
- if (bf>bf1) return (1);
- if (bf<NULL AND bf<-bf1) return (2);
-
- out[0]=bf << SFIXV;
-
- return(0);
-
- }
-
- /*************************************
- ** FUNZIONE PER PASSARE DA SINGLE **
- ** FLOAT A FIXPOINT. **
- *************************************
- **** INPUT : **
- ** in -> puntatore a single float **
- ** con valore da convertire. **
- ** out-> puntatore a intero long **
- ** con valore convertito. **
- **** OUTPUT: **
- ** ==0 -> tutto ok. **
- ** <>0 -> errore out non modificato**
- *************************************/
- long int GD_sfl2fix(in,out)
- REG(a0)float *in;
- REG(a1)long int *out;
- {
- long int max,it,frt;
- float ifix;
-
- it=in[0];
- ifix=FIXV;
-
- /* calcolo massimo valore convertibile */
- max=0x7fffffff >> SFIXV;
-
- if (it>=max) return (1);
- if (it<NULL AND it<=-it) return (2);
-
- out[0]=in[0]*ifix;
-
- return(0);
-
-
- }
-
- /*************************************
- ** FUNZIONE PER PASSARE DA DOUBLE **
- ** FLOAT A FIXPOINT. **
- *************************************
- **** INPUT : **
- ** in -> puntatore a double float **
- ** con valore da convertire. **
- ** out-> puntatore a intero long **
- ** con valore convertito. **
- **** OUTPUT: **
- ** ==0 -> tutto ok. **
- ** <>0 -> errore out non modificato**
- *************************************/
- long int GD_dfl2fix(in,out)
- REG(a0)double *in;
- REG(a1)long int *out;
- {
- long int max,it,frt;
- double ifix;
-
- it=in[0];
- ifix=FIXV;
-
- /* calcolo massimo valore convertibile */
- max=0x7fffffff >> SFIXV;
-
- if (it>=max) return (1);
- if (it<NULL AND it<=-it) return (2);
-
- out[0]=in[0]*ifix;
-
- return(0);
-
-
- }
-
- /*************************************
- ** FUNZIONE PER PASSARE DA FIXPOINT**
- ** AD INTERO **
- *************************************
- **** INPUT : **
- ** in -> puntatore a intero long **
- ** con valore da convertire. **
- ** out-> puntatore a intero long **
- ** con valore convertito. **
- **** OUTPUT: **
- ** ==0 -> tutto ok. **
- ** <>0 -> errore out non modificato**
- *************************************/
- long int GD_fix2int(in,out)
- REG(a0)long int *in;
- REG(a1)long int *out;
- {
- long int i;
-
- i=in[0];
- if (i<~0L - FIXVM) i=i+FIXVM;
-
- out[0]=i >> SFIXV;
-
- return(0);
-
- }
-
- /*************************************
- ** FUNZIONE PER PASSARE DA FIXPOINT**
- ** AD SINGLE FLOAT **
- *************************************
- **** INPUT : **
- ** in -> puntatore a intero long **
- ** con valore da convertire. **
- ** out-> puntatore a single float **
- ** con valore convertito. **
- **** OUTPUT: **
- ** ==0 -> tutto ok. **
- ** <>0 -> errore out non modificato**
- *************************************/
- long int GD_fix2sfl(in,out)
- REG(a0)long int *in;
- REG(a1)float *out;
- {
- float iv,fv,ifix;
-
- ifix=FIXV;
- fv=in[0] & MFRAC;
- iv=in[0]>>SFIXV;
-
- out[0]=iv+fv/ifix;
-
- return(0);
-
- }
-
- /*************************************
- ** FUNZIONE PER PASSARE DA FIXPOINT**
- ** AD DOUBLE FLOAT **
- *************************************
- **** INPUT : **
- ** in -> puntatore a intero long **
- ** con valore da convertire. **
- ** out-> puntatore a double float **
- ** con valore convertito. **
- **** OUTPUT: **
- ** ==0 -> tutto ok. **
- ** <>0 -> errore out non modificato**
- *************************************/
- long int GD_fix2dfl(in,out)
- REG(a0)long int *in;
- REG(a1)double *out;
- {
- double iv,fv,ifix;
-
- ifix=FIXV;
- fv=in[0] & MFRAC;
- iv=in[0]>>SFIXV;
-
- out[0]=iv+fv/ifix;
-
- return(0);
-
- }
-
- /*************************************
- ** FUNZIONE PER CAMBIARE IL MODO **
- ** VIDEO DI TRACCIAMENTO. **
- *************************************
- **** INPUT : **
- ** in -> valore >0 ritornato da **
- ** display3d(). **
- ** mod -> nuovo modo video. **
- **** NOTA : **
- ** valori per mod : **
- ** 0 > JAM1 (over 2) **
- ** 1 > JAM2 (over 0) (def.) **
- ** 2 > COMPLEMENT (over 1) **
- ** 4 > INVERSVID (inverse 1) **
- *************************************/
- void GD_over(REG(a0)struct ambient3d *in,REG(d0)long int mod)
- {
-
- over(in->graf,mod);
-
- }
-
- /*************************************
- ** FUNZIONE PER CANCELLARE UN BOX **
- ** NELLA FINESTRA . **
- *************************************
- **** INPUT : **
- ** in -> valore >0 ritornato da **
- ** display3d(). **
- ** x0 -> coord. x punto in alto **
- ** a sinistra box. **
- ** y0 -> coord. y punto in alto **
- ** a sinistra box. **
- ** x1 -> coord. x punto in basso **
- ** a destra box. **
- ** y1 -> coord. y punto in basso **
- ** a destra box. **
- **** NOTA : **
- ** usa il colore dello sfondo, e **
- ** non influenza le altre funzioni **
- *************************************/
- void GD_cls_b(REG(a0)struct ambient3d *in,REG(d0)long int x0,
- REG(d1)long int y0,REG(d2)long int x1,REG(d3)long int y1)
- {
- /*
- cls_b(in->graf,x0,y0,x1,y1);
- */
- }
-
- /***************** FINE ROUTIN USABILI ESTERNAMENTE ********************/
-
-